//
//  UIDevice+Ext.swift
//  TTCOM-iOS
//
//  Created by Toj on 7/4/22.
//

import UIKit
import CoreTelephony

// public enum NWStatus: NSInteger {
// case NotReachable = 0   // 无法识别
// case ReachableViaWWAN2G // 2G
// case ReachableViaWWAN3G // 3G
// case ReachableViaWWAN4G // 4G
// case ReachableViaWifi   // Wifi
// }

// MARK: - 设备信息

// 判断已经缓存
// 刘海
private var _notchSeriesCache = false
// 灵动岛
private var _isDynamicIsLandCache = false

// 缓存信息
private var _isNotchSeries = false
private var _isDynamicIsLand = false
private var _iOSName = ""

public extension UIDevice {
    
    /// 型号
    var dv_iOSName: String {
        guard _iOSName.isEmpty else { return _iOSName }
        
        _iOSName = iOSNames[dv_machine] ?? "Unknown device, Maybe it's new"
        return _iOSName
    }
    
    /**
     * 设备的唯一ID, 格式为UUID字符串.
     * 但是, 该ID并不是设备序列号, 而且可以被用户重置
     * e.g. "DFEC3F18-46E8-404D-A845-C2AC5AA034CD"
     */
    var dv_identifier: String {
        return identifierForVendor?.uuidString ?? ""
    }
    
    // 判断 刘海 系列
    var dv_isNotchSeries: Bool {
        if _notchSeriesCache { return _isNotchSeries }
        
        // 缓存下次不需要再次执行
        _notchSeriesCache = true
        let safeAreaInsetBottom = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
        _isNotchSeries = safeAreaInsetBottom > 0
        return _isNotchSeries
    }
    
    // 判断 灵动岛 系列
    var dv_isDynamicIsLand: Bool {
        if _isDynamicIsLandCache { return _isDynamicIsLand }
        
        // 缓存下次不需要再次执行
        _isDynamicIsLandCache = true
        return _isDynamicIsLand
    }
}


// MARK: - 当前硬件信息类型
enum UIDeviceUTSName: String {
    case sysname // 当前操作系统名称
    case nodename // 手机在网络上的名称
    case release // 当前发布级别
    case version // 当前发布版本
    case machine // 当前硬件体系类型
}

// MARK: - 当前硬件信息
// 缓存信息
private var _machine = ""
private var _machine2 = ""
private var _sysname = ""
private var _nodename = ""
private var _release = ""
private var _version = ""
public extension UIDevice {
    
    /** 机型标识符: e.g. "iPhone7,2" */
    var dv_machine: String {
        guard _machine.isEmpty else { return _machine }
        
        var systemInfo = utsname()
        uname(&systemInfo)
        let machine = withUnsafePointer(to: &systemInfo.machine.0) { ptr in
            return String(cString: ptr)
        }
        _machine = machine
        return _machine
    }
    
    /** 获取设备信息 */
    private func dv_info(type: UIDeviceUTSName) -> Mirror {
        var systemInfo = utsname()
        uname(&systemInfo)
        switch type {
        case .sysname:
            return Mirror(reflecting: systemInfo.sysname)
        case .nodename:
            return Mirror(reflecting: systemInfo.nodename)
        case .release:
            return Mirror(reflecting: systemInfo.release)
        case .version:
            return Mirror(reflecting: systemInfo.version)
        case .machine:
            return Mirror(reflecting: systemInfo.machine)
        }
    }
    
    private func dv_systemInfo(type: UIDeviceUTSName) -> String {
        let machineMirror = dv_info(type: type)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
        
        return identifier
    }
    
    /** 操作系统内核名称: e.g. "Darwin" */
    var dv_sysname: String {
        guard _sysname.isEmpty else { return _sysname }
        
        _sysname = dv_systemInfo(type: .sysname)
        return _sysname
    }
    
    /** 手机在网络上的名称: e.g. "My iphone" */
    var dv_nodename: String {
        guard _nodename.isEmpty else { return _nodename }
        
        _nodename = dv_systemInfo(type: .nodename)
        return _nodename
    }
    
    /** 内核版本: e.g. "18.7.0" */
    var dv_release: String {
        guard _release.isEmpty else { return _release }
        
        _release = dv_systemInfo(type: .release)
        return _release
    }
    
    /**
     * 内核版本信息
     * e.g. "Darwin Kernel Version 18.7.0: Fri Aug 19 23:28:26 PDT 2022; root:xnu-4903.272.5~1/RELEASE_ARM64_T7000"
     ** 1. Darwin: 这是XNU内核名称
     ** 2. 18.7.0.: 这里显示内核版本号
     ** 3. Fri Aug 19 23:28:26 PDT 2022: 这是这个内核Release版本的发布日期
     ** 4. root:xnu-4903.272.5~1: 这是内核映像文件的路径信息.
     ** 5. RELEASE_ARM64_T7000: 这是这个内核版本的开发代号, 通常包含CPU架构和设备代号信息
     *** ARM64: 代表64位ARM处理器架构
     *** T7000: 可能代表某款iPhone的代号
     */
    var dv_version: String {
        guard _version.isEmpty else { return _version }
        
        _version = dv_systemInfo(type: .version)
        return _version
    }
    
    /** 机型标识符: e.g. "iPhone7,2", 与 dv_machine 雷同, 推荐dv_machine */
    var dv_machine2: String {
        guard _machine2.isEmpty else { return _machine2 }
        
        _machine2 = dv_systemInfo(type: .machine)
        return _machine2
    }
}

// MARK: - 手机卡信息
public extension UIDevice {
    
    /// 手机卡的运营商 多卡用户 运营商逗号分隔. e.g. "中国联通"
    var tp_carrierName: String {
        let networkInfo = CTTelephonyNetworkInfo()
        let carrierName = networkInfo.subscriberCellularProvider?.carrierName ?? ""
        return carrierName
    }
    
    /// MCC: 移动电话国家码. e.g. "460": 中国
    var tp_countryCode: String {
        let networkInfo = CTTelephonyNetworkInfo()
        let mobileCountryCode = networkInfo.subscriberCellularProvider?.mobileCountryCode ?? ""
        return mobileCountryCode
    }
    
    /**
     * MNC: 移动网络号码, 用于识别移动客户所属的移动网络
     * e.g.
     * 00: 中国移动
     * 01: 中国联通
     * 02: 中国移动
     * 03: 中国电信
     * 04: 中国移动
     * 06: 中国联通
     * 07: 中国移动
     * 08: 中国移动
     * 09: 中国联通
     * 10: 中国联通
     * 11: 中国电信
     * 12: 中国电信
     * 13: 中国移动
     */
    var tp_networkCode: String {
        let networkInfo = CTTelephonyNetworkInfo()
        let mobileNetworkCode = networkInfo.subscriberCellularProvider?.mobileNetworkCode ?? ""
        return mobileNetworkCode
    }
    
    /// 国家代码. e.g. "CN": 中国
    var tp_isoCountryCode: String {
        let networkInfo = CTTelephonyNetworkInfo()
        let isoCountryCode = networkInfo.subscriberCellularProvider?.isoCountryCode ?? ""
        return isoCountryCode
    }
    
    /// 语音传输功能
    var tp_isAllowsVOIP: Bool {
        let networkInfo = CTTelephonyNetworkInfo()
        let allowsVOIP = networkInfo.subscriberCellularProvider?.allowsVOIP ?? false
        return allowsVOIP
    }
}
